home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / util / cdity / Yak210src.lha / Yak_2.10_Src / WBStartup / Unixdirs.c < prev    next >
C/C++ Source or Header  |  1995-06-16  |  14KB  |  508 lines

  1. /*
  2. ** Patches dos.library functions to allow use of '.' and '..' ala UNIX.
  3. ** Largely inspired from UnixDirsII from Martin Scott.
  4. **
  5. ** List of patched functions :
  6. **
  7. **     AssignLate
  8. **     AssignPath
  9. **     CreateDir
  10. **     DeleteFile
  11. **     LoadSeg
  12. **     Lock
  13. **     MakeLink
  14. **     MatchFirst
  15. **     NewLoadSeg
  16. **     Open
  17. **     ParsePattern
  18. **     Rename
  19. **     SetComment
  20. **     SetFileDate
  21. **     SetProtection
  22. **
  23. ** Author: Gael Marziou
  24. ** Created: 14 July 94 (Bastille day ;-)
  25. **
  26. **
  27. */
  28.  
  29. #define __USE_SYSBASE
  30.  
  31. #include <exec/types.h>
  32. #include <exec/execbase.h>
  33. #include <exec/memory.h>
  34. #include <exec/semaphores.h>
  35. #include <dos/dos.h>
  36. #include <libraries/commodities.h>
  37. #include <string.h>
  38. #include <proto/dos.h>
  39. #include <proto/exec.h>
  40.  
  41. #include "Patch_Libs.h"
  42. #include "yak.h"
  43. #include "Settings.h"
  44.  
  45. /* Local protos */
  46. SAVEDS BOOL adjustpath(UBYTE *path, UBYTE *newpath, LONG len);
  47.  
  48. /* The number of 'replacement' functions for UnixDirs feature */
  49. #define UNIXDIRS_NUMBEROFFUNCTIONS (15)
  50.  
  51. /* declare stuff for standard one-parameter function */
  52. /* UBYTE * in d1 */
  53. #define DEC11_OLD(oldname) LONG (*ASM oldname) (REG(d1) UBYTE *, REG(a6) struct Library *base)
  54. #define DEC11_NEW(newname) SAVEDS LONG ASM newname(REG(d1) UBYTE *, REG(a6) struct Library *base)
  55. #define DEC11(name) DEC11_OLD(old## name); DEC11_NEW(new## name); DEC_LVO(LVO## name)
  56.  
  57. /* declare stuff for standard two-parameter function */
  58. /* UBYTE * in d1 */
  59. #define DEC21_OLD(oldname) LONG (*ASM oldname) (REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *base)
  60. #define DEC21_NEW(newname) SAVEDS LONG ASM newname(REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *base)
  61. #define DEC21(name) DEC21_OLD(old## name); DEC21_NEW(new## name); DEC_LVO(LVO## name)
  62.  
  63. /* declare stuff for standard two-parameter function */
  64. /* UBYTE * in d2 */
  65. #define DEC22_OLD(oldname) LONG (*ASM oldname) (REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *base)
  66. #define DEC22_NEW(newname) SAVEDS LONG ASM newname(REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *base)
  67. #define DEC22(name) DEC22_OLD(old## name); DEC22_NEW(new## name); DEC_LVO(LVO## name)
  68.  
  69. /* the patched functions themselves */
  70. DEC22(AssignLate);
  71. DEC22(AssignPath);
  72. DEC11(CreateDir);
  73. DEC11(DeleteFile);
  74. DEC11(LoadSeg);
  75. DEC21(Lock);
  76. DEC21(MatchFirst);
  77. DEC21(NewLoadSeg);
  78. DEC21(Open);
  79. DEC21(SetComment);
  80. DEC21(SetFileDate);
  81. DEC21(SetProtection);
  82.  
  83.  
  84. /* manually declared, because different from standard */
  85.  
  86. LONG (*ASM oldMakeLink) (REG(d1) UBYTE *, REG(d2) LONG, REG(d3) LONG, REG(a6) struct Library *);
  87. SAVEDS LONG ASM newMakeLink(REG(d1) UBYTE *, REG(d2) LONG, REG(d3) LONG, REG(a6) struct Library *);
  88. extern LVOMakeLink;
  89.  
  90. LONG (*ASM oldRename) (REG(d1) UBYTE *, REG(d2) UBYTE *, REG(a6) struct Library *);
  91. SAVEDS LONG ASM newRename(REG(d1) UBYTE *, REG(d2) UBYTE *, REG(a6) struct Library *);
  92. extern LVORename;
  93.  
  94. LONG (*ASM oldParsePattern) (REG(d1) UBYTE *, REG(d2) UBYTE *, REG(d3) LONG, REG(a6) struct Library *);
  95. SAVEDS LONG ASM newParsePattern(REG(d1) UBYTE *, REG(d2) UBYTE *, REG(d3) LONG, REG(a6) struct Library *);
  96. extern LVOParsePattern;
  97.  
  98. struct LVOTable LVOArrayUnixDirs[] =
  99. {
  100.     {(LONG)&LVOCreateDir, (struct Library *)&DOSBase, (ULONG)&oldCreateDir, (ULONG)&newCreateDir },
  101.     {(LONG)&LVODeleteFile, (struct Library *)&DOSBase, (ULONG)&oldDeleteFile, (ULONG)&newDeleteFile },
  102.     {(LONG)&LVOLoadSeg, (struct Library *)&DOSBase, (ULONG)&oldLoadSeg, (ULONG)&newLoadSeg },
  103.  
  104.     {(LONG)&LVOLock, (struct Library *)&DOSBase, (ULONG)&oldLock, (ULONG)&newLock },
  105.     {(LONG)&LVONewLoadSeg, (struct Library *)&DOSBase, (ULONG)&oldNewLoadSeg, (ULONG)&newNewLoadSeg },
  106.     {(LONG)&LVOOpen, (struct Library *)&DOSBase, (ULONG)&oldOpen, (ULONG)&newOpen },
  107.  
  108.     {(LONG)&LVOSetComment, (struct Library *)&DOSBase, (ULONG)&oldSetComment, (ULONG)&newSetComment },
  109.     {(LONG)&LVOSetFileDate, (struct Library *)&DOSBase, (ULONG)&oldSetFileDate, (ULONG)&newSetFileDate },
  110.  
  111.     {(LONG)&LVOSetProtection, (struct Library *)&DOSBase, (ULONG)&oldSetProtection, (ULONG)&newSetProtection },
  112.     {(LONG)&LVOAssignLate, (struct Library *)&DOSBase, (ULONG)&oldAssignLate, (ULONG)&newAssignLate },
  113.     {(LONG)&LVOAssignPath, (struct Library *)&DOSBase, (ULONG)&oldAssignPath, (ULONG)&newAssignPath },
  114.     {(LONG)&LVORename, (struct Library *)&DOSBase, (ULONG)&oldRename, (ULONG)&newRename },
  115.     {(LONG)&LVOMakeLink, (struct Library *)&DOSBase, (ULONG)&oldMakeLink, (ULONG)&newMakeLink },
  116.     {(LONG)&LVOMatchFirst, (struct Library *) & DOSBase, (ULONG)&oldMatchFirst, (ULONG)&newMatchFirst },
  117.     {(LONG)&LVOParsePattern, (struct Library *) & DOSBase, (ULONG)&oldParsePattern, (ULONG)&newParsePattern }
  118. };
  119.  
  120.  
  121. struct UnixDirsJumpTable
  122. {
  123.     struct SignalSemaphore jt_Semaphore;
  124.     UWORD pad_word;
  125.     struct Task *jt_Owner;
  126.     UBYTE jt_Function[UNIXDIRS_NUMBEROFFUNCTIONS * 6];
  127. };
  128.  
  129. /* Strings */
  130. /* The name this JumpTable/Semaphore will get. */
  131. static UBYTE *UnixDirsJTName = "YakUnixDirs-JT";
  132.  
  133. static BOOL UnixDirsPatchInstalled = FALSE;
  134.  
  135.  
  136. __regargs void
  137. ToggleUnixDirs( BOOL toggle )
  138. {
  139.     if (toggle == TRUE)
  140.     {
  141.         if (UnixDirsPatchInstalled == FALSE)
  142.         {
  143.             InstallWedge(UnixDirsJTName, 
  144.                          LVOArrayUnixDirs, 
  145.                          (UBYTE) UNIXDIRS_NUMBEROFFUNCTIONS);
  146.             UnixDirsPatchInstalled = TRUE;
  147.         }
  148.     }
  149.     else
  150.     {
  151.         if (UnixDirsPatchInstalled == TRUE)
  152.         {
  153.             RemoveWedge(UnixDirsJTName, 
  154.                         LVOArrayUnixDirs, 
  155.                         (UBYTE) UNIXDIRS_NUMBEROFFUNCTIONS);
  156.             UnixDirsPatchInstalled = FALSE;
  157.         }
  158.     }
  159. }
  160.  
  161.  
  162. /******************************************************************************/
  163. /*******************                                 **************************/
  164. /*******************   NEW DOS ROUTINES START HERE   **************************/
  165. /*******************                                 **************************/
  166. /******************************************************************************/
  167.  
  168. /********************************************
  169.  
  170. Example of the simplest patch (does nothing)
  171.  
  172. SAVEDS LONG ASM
  173. new(REG(d1) LONG arg1, REG(d2) LONG arg2,
  174.         REG(a6) struct Library *base)
  175. {
  176.     return old(arg1, arg2, base);
  177. }
  178.  
  179. ********************************************/
  180.  
  181. /*
  182.  * These are the generic patch routines.
  183.  * They handle most patches automatically.
  184.  */
  185.  
  186. #define PATHSIZE    512L    /* enough for most purposes? */
  187.  
  188. /* 1 args, convert arg in d1 */
  189. LONG ASM Wedge11 (REG(a0) LONG (*ASM dosroutine)(REG(d1) UBYTE *, REG(a6) struct Library *),
  190.                                   REG(d1) UBYTE *arg1, 
  191.                                   REG(a6) struct Library *base)
  192. {
  193.     struct SignalSemaphore *jt;
  194.     UBYTE *newpath;
  195.     LONG rc = 0;
  196.  
  197.     if (jt = FindSemaphore(UnixDirsJTName))
  198.     {
  199.         ObtainSemaphoreShared(jt);
  200.  
  201.         if (newpath = AllocVec(PATHSIZE, 0L))
  202.         {
  203.             if (adjustpath(arg1, newpath, PATHSIZE))
  204.                 rc = dosroutine(newpath, base);
  205.             else
  206.                 rc = dosroutine(arg1, base);
  207.  
  208.             FreeVec(newpath);
  209.         }
  210.         else SetIoErr(ERROR_NO_FREE_STORE);
  211.  
  212.         ReleaseSemaphore(jt);
  213.     }
  214.     return rc;
  215. }
  216.  
  217. /* 2 args, convert arg in d1 */
  218. LONG ASM Wedge21 (REG(a0) LONG (*ASM dosroutine)(REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *),
  219.                   REG(d1) UBYTE *arg1,
  220.                       REG(d2) LONG arg2, 
  221.                   REG(a6) struct Library *base)
  222. {
  223.     struct SignalSemaphore *jt;
  224.     UBYTE *newpath;
  225.     LONG rc = 0;
  226.  
  227.     if (jt = FindSemaphore(UnixDirsJTName))
  228.     {
  229.         ObtainSemaphoreShared(jt);
  230.  
  231.         if (newpath = AllocVec(PATHSIZE, 0L))
  232.         {
  233.             if (adjustpath(arg1, newpath, PATHSIZE))
  234.                 rc = dosroutine(newpath, arg2, base);
  235.             else
  236.                 rc = dosroutine(arg1, arg2, base);
  237.             FreeVec(newpath);
  238.         }
  239.         else SetIoErr(ERROR_NO_FREE_STORE);
  240.  
  241.         ReleaseSemaphore(jt);
  242.     }
  243.     return rc;
  244. }
  245.  
  246. /* 2 args, convert arg in d2 */
  247.  
  248. LONG ASM Wedge22 (REG(a0) LONG (*ASM dosroutine)(REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *),
  249.                   REG(d1) LONG arg1,
  250.                       REG(d2) UBYTE *arg2, 
  251.                   REG(a6) struct Library *base)
  252. {
  253.     struct SignalSemaphore *jt;
  254.     UBYTE *newpath;
  255.     LONG rc = 0;
  256.  
  257.     if (jt = FindSemaphore(UnixDirsJTName))
  258.     {
  259.         ObtainSemaphoreShared(jt);
  260.  
  261.         if (newpath = AllocVec(PATHSIZE, 0L))
  262.         {
  263.             if (adjustpath(arg2, newpath, PATHSIZE))
  264.                 rc = dosroutine(arg1, newpath, base);
  265.             else
  266.                 rc = dosroutine(arg1, arg2, base);
  267.  
  268.             FreeVec(newpath);
  269.         }
  270.         else SetIoErr(ERROR_NO_FREE_STORE);
  271.  
  272.         ReleaseSemaphore(jt);
  273.     }
  274.     return rc;
  275. }
  276.  
  277. #define PATCH11(name) \
  278. SAVEDS LONG ASM \
  279. new## name(REG(d1) UBYTE *arg1, \
  280.     REG(a6) struct Library *base) \
  281. { return Wedge11(old## name, arg1, base); }
  282.  
  283. #define PATCH21(name) \
  284. SAVEDS LONG ASM \
  285. new## name(REG(d1) UBYTE *arg1, REG(d2) LONG arg2, \
  286.     REG(a6) struct Library *base) \
  287. { return Wedge21(old## name, arg1, arg2, base); }
  288.  
  289. #define PATCH22(name) \
  290. SAVEDS LONG ASM \
  291. new## name(REG(d1) LONG arg1, REG(d2) UBYTE *arg2, \
  292.     REG(a6) struct Library *base) \
  293. { return Wedge22(old## name, arg1, arg2, base); }
  294.  
  295. PATCH22(AssignLate)
  296. PATCH22(AssignPath)
  297. PATCH11(CreateDir)
  298. PATCH11(DeleteFile)
  299. PATCH11(LoadSeg)
  300. PATCH21(Lock)
  301. PATCH21(MatchFirst)
  302. PATCH21(NewLoadSeg)
  303. PATCH21(Open)
  304. PATCH21(SetComment)
  305. PATCH21(SetFileDate)
  306. PATCH21(SetProtection)
  307.  
  308. /*** And the following routines are handmade ***/
  309.  
  310. SAVEDS LONG ASM
  311. newRename(REG(d1) UBYTE *oldname, REG(d2) UBYTE *newname,
  312.       REG(a6) struct Library *base)
  313. {
  314.     struct SignalSemaphore *jt;
  315.     UBYTE *from, *to;
  316.     LONG rc = 0;
  317.  
  318.     if (jt = FindSemaphore(UnixDirsJTName))
  319.     {
  320.         ObtainSemaphoreShared(jt);
  321.  
  322.         if (from = AllocVec(PATHSIZE, 0L))
  323.         {
  324.             adjustpath(oldname, from, PATHSIZE);
  325.             if (to = AllocVec(PATHSIZE, 0L))
  326.             {
  327.                 adjustpath(newname, to, PATHSIZE);
  328.                 rc = oldRename(from, to, base);
  329.                 FreeVec(to);
  330.             }
  331.             else SetIoErr(ERROR_NO_FREE_STORE);
  332.             FreeVec(from);
  333.         }
  334.         else SetIoErr(ERROR_NO_FREE_STORE);
  335.  
  336.         ReleaseSemaphore(jt);
  337.     }
  338.     return rc;
  339. }
  340.  
  341.  
  342. /* a bit more suspect this; will buflen be big enough given a . substitution? */
  343. SAVEDS LONG ASM
  344. newParsePattern(REG(d1) UBYTE *pat, 
  345.                 REG(d2) UBYTE *buf, 
  346.                 REG(d3) LONG buflen,
  347.                 REG(a6) struct Library *base)
  348. {
  349.     struct SignalSemaphore *jt;
  350.     UBYTE *newpat;
  351.     LONG rc = 0;
  352.  
  353.     if (jt = FindSemaphore(UnixDirsJTName))
  354.     {
  355.         ObtainSemaphoreShared(jt);
  356.  
  357.         if (newpat = AllocVec(PATHSIZE, 0L))
  358.         {
  359.             adjustpath(pat, newpat, PATHSIZE);
  360.             rc = oldParsePattern(newpat, buf, buflen, base);
  361.             FreeVec(newpat);
  362.         }
  363.         else SetIoErr(ERROR_NO_FREE_STORE);
  364.  
  365.         ReleaseSemaphore(jt);
  366.     }
  367.     return rc;
  368. }
  369.  
  370.  
  371. SAVEDS LONG ASM
  372. newMakeLink (REG(d1) UBYTE *name, 
  373.              REG(d2) LONG dest,
  374.              REG(d3) LONG soft,
  375.              REG(a6) struct Library *base)
  376. {
  377.     struct SignalSemaphore *jt;
  378.     UBYTE *from, *to;
  379.     LONG rc = 0;
  380.  
  381.     if (jt = FindSemaphore(UnixDirsJTName))
  382.     {
  383.         ObtainSemaphoreShared(jt);
  384.  
  385.         if (from = AllocVec(PATHSIZE, 0L))
  386.         {
  387.             adjustpath(name, from, PATHSIZE);
  388.             if (soft)
  389.             {
  390.                 /* dest points to a null-terminated path string */
  391.                 if (to = AllocVec(PATHSIZE, 0L))
  392.                 {
  393.                     adjustpath((STRPTR)dest, to, PATHSIZE);
  394.                     rc = oldMakeLink(from, (LONG)to, soft, base);
  395.                     FreeVec(to);
  396.                 }
  397.                 else SetIoErr(ERROR_NO_FREE_STORE);
  398.             }
  399.             else
  400.             {
  401.                 /* dest is a lock (BPTR) */
  402.                 rc = oldMakeLink(from, dest, soft, base);
  403.             }
  404.             FreeVec(from);
  405.         }
  406.         else SetIoErr(ERROR_NO_FREE_STORE);
  407.  
  408.         ReleaseSemaphore(jt);
  409.     }
  410.     return rc;
  411. }
  412.  
  413.  
  414.  
  415.  
  416. /*
  417.  * Routine to convert a UNIX-style path to an AmigaDOS path.
  418.  * A UNIX-style path is understood here as follows:
  419.  * 
  420.  *  leading . means current dir; like "", but filled in explicitly
  421.  *  ../ means /
  422.  *  ..  means /
  423.  * 
  424.  * Written as part of UnixDirs2, a (to be written) system patch which allows
  425.  * use of UNIX-style paths everywhere.
  426.  * 
  427.  * Martin W. Scott,  8 January 1993
  428.  */
  429.  
  430.  
  431. /* insert $cwd into s, return pointer to next free char */
  432. SAVEDS char *
  433. insertcwd(char *s, LONG len)
  434. {
  435.     if (NameFromLock(((struct Process *)(((struct ExecBase *)SysBase)->ThisTask))->pr_CurrentDir, s, len))
  436.     {
  437.         while (*s)
  438.             s++;
  439.     }
  440.     return s;
  441. }
  442.  
  443. /* adjust path from UNIX-style to Amiga-style */
  444. /* TO DO: length checking when building new path */
  445. SAVEDS BOOL
  446. adjustpath(UBYTE *path, UBYTE *newpath, LONG len)
  447. {
  448.     UBYTE *s, *t;
  449. #ifdef DEBUG
  450.     char *origpath = path;
  451. #endif
  452.  
  453.     s = newpath;
  454.  
  455.     if (path == NULL)   /* bypass */
  456.         return FALSE;
  457.  
  458.     if (slashdir && (path[0] == '/')) 
  459.     {
  460.         path[0]=':';   /* to accommodate unix-style root paths */
  461.     }
  462.  
  463.     if (t = strchr(path, ':'))      /* check for ':' in path */
  464.     {
  465.         t++;                /* copy device component */
  466.         while (path < t)
  467.             *s++ = *path++;
  468.     }
  469.     else if (path[0] == '.')        /*** translate '.' to $cwd ***/
  470.     {
  471.         if (!path[1])           /* only "." */
  472.         {
  473.             s = insertcwd(s, len);
  474.             path++;         /* path[0] == '\0' - STOP */
  475.         }
  476.         else if (path[1] == '/')    /* initial component is $cwd */
  477.         {
  478.             s = insertcwd(s, len);
  479.             if (*(s-1) != ':')
  480.                 *s++ = '/'; /* copy '/', increment pointers */
  481.             path += 2;
  482.         }
  483.     }
  484.  
  485.     while (path[0])         /*** copy remainder of path ***/
  486.     {
  487.         if (path[0] == '.' && path[1] == '.')
  488.         {
  489.             if (path[2] == '/') /* just skip "..", copying '/' */
  490.             {
  491.                 path += 2;
  492.                 *s++ = *path++;
  493.             }
  494.             else if (!path[2])  /* append '/' and stop */
  495.             {
  496.                 path += 2;
  497.                 *s++ = '/';
  498.             }
  499.             else *s++ = *path++;
  500.         }
  501.         else *s++ = *path++;
  502.     }
  503.     *s = '\0';
  504.  
  505.     return TRUE;
  506. }
  507.  
  508.